home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CIconBuddy / CIconBuddy.c next >
Encoding:
C/C++ Source or Header  |  1994-11-30  |  9.3 KB  |  372 lines  |  [TEXT/KAHL]

  1. /* CIconBuddy.c
  2.  *    An icon pane/button class based on the System 7 icon buddy calls that
  3.  *    draw/track icon suites.  See Tech Note M.IM.IconDrawing for more details.
  4.  *
  5.  *    SUPERCLASS = CPane.c
  6.  *
  7.  *    Copyright ©1992, Mark/Space Softworks, All Rights Reserved
  8.  *
  9.  *    This class is buyware, if you use it, buy a Mark/Space Softworks product.
  10.  *    Send email to one of the below addresses for more details.
  11.  *        Internet:    mspace@netcom.com
  12.  *        AppleLink:    MARKSPACE
  13.  *        AOL:        markspace
  14.  *    
  15.  *    12/12/92    bhall    Created
  16.  *    12/14/92    bhall    Cleaned up for submission to TCL-TALK
  17.  *    10/10/93    bhall    Fixed leak in DrawIcon
  18.  */
  19.  
  20. #include <CIconBuddy.h>
  21. #include <Commands.h>
  22. #include <Global.h>
  23. #include <SUtil.h>
  24.  
  25. #include <Icons.h>
  26.  
  27. RgnHandle CIconBuddy::cIconRgn;
  28.  
  29. /*******************************************************************************\
  30. * IIconBuddy                                                                    *
  31. *     Initialize an Icon Buddy. The icons are taken from an icon family with the    *
  32. *     specified ID.                                                                *
  33. *                                                                                *
  34. \*******************************************************************************/
  35. void CIconBuddy::IIconBuddy(
  36.     CView            *anEnclosure,
  37.     CBureaucrat        *aSupervisor,
  38.     short            aWidth,
  39.     short            aHeight,
  40.     short            aHEncl,
  41.     short            aVEncl,
  42.     SizingOption    aHSizing,
  43.     SizingOption    aVSizing,
  44.     short            iconID,
  45.     Boolean            fPreferColor)
  46. {    
  47.     /*
  48.      * Initialize our superclass
  49.      */
  50.     CPane::IPane(
  51.         anEnclosure, aSupervisor,
  52.         aWidth, aHeight,
  53.         aHEncl, aVEncl,
  54.         aHSizing, aVSizing);
  55.     
  56.     /*
  57.      * Init our instance variables
  58.      */
  59.     this->iconID = iconID;
  60.     clickCmd = cmdNull;
  61.  
  62.     IIconBuddyX(fPreferColor);
  63. }
  64.  
  65.  
  66. /*******************************************************************************\
  67. * IViewTemp                                                                        *
  68. *    Initialize from a 'IcPn' resource.                                            *
  69. *                                                                                *
  70. \*******************************************************************************/
  71. void CIconBuddy::IViewTemp(
  72.     CView *anEnclosure, CBureaucrat *aSupervisor, Ptr viewData)
  73. {
  74.     tIconPaneTempP iconData = (tIconPaneTempP) viewData;
  75.     
  76.     inherited::IViewTemp(anEnclosure, aSupervisor, viewData);
  77.  
  78.     /*
  79.      * Init our instance variables
  80.      */
  81.     iconID = iconData->iconID;
  82.     clickCmd = iconData->clickCmd;
  83.     
  84.     IIconBuddyX(iconData->fPreferColor);
  85. }
  86.  
  87.  
  88. /*******************************************************************************\
  89. * IIconPaneX                                                                    *
  90. *    Perform common initialization.                                                *
  91. *                                                                                *
  92. \*******************************************************************************/
  93. void CIconBuddy::IIconBuddyX(Boolean fPreferColor)
  94. {
  95.     /*
  96.      * Init instance data not handled by IViewTemp or IIconBuddy
  97.      */
  98.     align = atNone;
  99.     allowDistortion = FALSE;
  100.     
  101.     if (!cIconRgn)
  102.         cIconRgn = NewRgn();
  103. }
  104.  
  105.  
  106. #pragma mark -
  107.  
  108. /*******************************************************************************\
  109. * Get/SetIconID                                                                    *
  110. *     Get/Set the id of the icon suite to use for this button.                    *
  111. *                                                                                *
  112. \*******************************************************************************/
  113. void CIconBuddy::SetIconID(short anID)
  114. {
  115.     iconID = anID;
  116. }
  117.  
  118.  
  119. short CIconBuddy::GetIconID(void)
  120. {
  121.     return iconID;
  122. }
  123.  
  124.  
  125. /*******************************************************************************\
  126. * Get/SetAlignment                                                                *
  127. *     Get/Set the alignment used in PlotIconID calls.                                *
  128. *                                                                                *
  129. \*******************************************************************************/
  130. void CIconBuddy::SetAlignment(IconAlignmentType anAlign)
  131. {
  132.     align = anAlign;
  133. }
  134.  
  135.  
  136. IconAlignmentType CIconBuddy::GetAlignment(void)
  137. {
  138.     return align;
  139. }
  140.  
  141.  
  142. #pragma mark -
  143.  
  144. /*******************************************************************************\
  145. * Activate/Deactivate                                                            *
  146. *     We need to redraw on an activate or deactivate event.                        *
  147. *                                                                                *
  148. \*******************************************************************************/
  149. void CIconBuddy::Activate(void)
  150. {
  151.     Boolean        wasActive = active;
  152.  
  153.     inherited::Activate();
  154.     
  155.     /*
  156.      * Don't draw if we don't have to
  157.      */
  158.     if (!wasActive && ReallyVisible()) {
  159.         Prepare();
  160.         DrawIcon(FALSE);
  161.     }
  162. }
  163.  
  164.  
  165. void CIconBuddy::Deactivate(void)
  166. {
  167.     Boolean        wasActive = active;
  168.  
  169.     inherited::Deactivate();
  170.  
  171.     /*
  172.      * Don't draw if we don't have to
  173.      */
  174.     if (wasActive && ReallyVisible()) {
  175.         Prepare();
  176.         DrawIcon(FALSE);
  177.     }
  178. }
  179.  
  180.  
  181. #pragma mark -
  182.  
  183. /*******************************************************************************\
  184. * GetIconRect                                                                    *
  185. *    This routine bottlenecks the retrieval of the rect used in the icon buddy    *
  186. *    calls.  If allowDistortion is TRUE, we just return the frame.  If it is        *
  187. *    false, we snap the rect to a valid 32, 16, or 12 pixel square.  This makes    *
  188. *    sure that the icon is not shrunk or blown up when drawn.                    *
  189. *                                                                                *
  190. *    For example, you may have a 16 * 14 images (in an ics) that you would like    *
  191. *    to display next to a scroll bar.  To do this you would draw the icon in        *
  192. *    a 16 * 16 rect, but specify a 16 * 14 frame.  If allowDistortion is true,    *
  193. *    the 16*16 ics would be distorted to fit the 16 * 14 frame.  If it were        *
  194. *    set to false, it would draw as intended, with view clipping preventing the    *
  195. *    rest of the (unused) imgae from stamping on the surrounding area.            *
  196. *                                                                                *
  197. \*******************************************************************************/
  198. void CIconBuddy::GetIconRect(Rect *theRect)
  199. {
  200.     LongToQDRect(&frame, theRect);
  201.     if (!allowDistortion) {
  202.         if (theRect->right > 16) {
  203.             theRect->right = 32;
  204.             theRect->bottom = 32;
  205.         } else if (theRect->right > 12) {
  206.             theRect->right = 16;
  207.             theRect->bottom = 16;
  208.         } else {
  209.             theRect->right = 12;
  210.             theRect->bottom = 12;
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216. /*******************************************************************************\
  217. * DrawIcon                                                                        *
  218. *    Draw the icon normally or hilited.                                            *
  219. *                                                                                *
  220. \*******************************************************************************/
  221. void CIconBuddy::DrawIcon(Boolean fHilite)
  222. {
  223.     IconTransformType    transform;
  224.     Rect                iconRect;
  225.     RgnHandle            iconRgn = NULL;
  226.  
  227.     /*
  228.      * Figure out the transform to use
  229.      */
  230.     if (fHilite)
  231.         transform = ttSelected;
  232.     else
  233.         transform = ttNone;
  234.     
  235.     if (!IsActive())
  236.         transform |= ttDisabled;
  237.     
  238.  
  239.     /*
  240.      * Draw the icon
  241.      */
  242.     GetIconRect(&iconRect);
  243.     FailOSErr(PlotIconID(&iconRect, align, transform, iconID));
  244.  
  245.     /*
  246.      * Validate the icon region, so we don't draw squares
  247.      */
  248.     IconIDToRgn(cIconRgn, &iconRect, align, iconID);
  249.     ValidRgn(cIconRgn);
  250.     SetEmptyRgn(cIconRgn);
  251. }
  252.  
  253.  
  254. /*******************************************************************************\
  255. * Draw                                                                            *
  256. *    Draw the icon in response to an update.                                        *
  257. *                                                                                *
  258. \*******************************************************************************/
  259. void CIconBuddy::Draw(Rect *area)
  260. {
  261.     DrawIcon(FALSE);
  262. }
  263.  
  264.  
  265. #pragma mark -
  266.  
  267. /*******************************************************************************\
  268. * SetClickCmd                                                                    *
  269. *     Set the clickCmd for an iconPane. This command will be sent to                *
  270. *     itsSupervisor when the icon is clicked and the mouse is released            *
  271. *     inside the icon.                                                            *
  272. *                                                                                *
  273. \*******************************************************************************/
  274. void CIconBuddy::SetClickCmd(long aCmd)
  275. {
  276.     clickCmd = aCmd;
  277. }
  278.  
  279.  
  280. /*******************************************************************************\
  281. * GetClickCmd                                                                    *
  282. *    Return the pane's clickCmd.                                                    *
  283. *                                                                                *
  284. \*******************************************************************************/
  285. long CIconBuddy::GetClickCmd(void)
  286. {
  287.     return clickCmd;
  288. }
  289.  
  290.  
  291. /*******************************************************************************\
  292. * SimulateClick                                                                    *
  293. *    Simulate a click in the button, usually requested in response to            *
  294. *    a keyboard shortcut.                                                        *
  295. *                                                                                *
  296. \*******************************************************************************/
  297. void CIconBuddy::SimulateClick(void)
  298. {
  299.     #define kFlashDelay        8    //  number of ticks to hilite button
  300.     long    ticks;
  301.     
  302.     if (!IsActive())
  303.         return;
  304.  
  305.     /*
  306.      * Flash the button
  307.      */
  308.     Prepare();
  309.     DrawIcon(TRUE);
  310.     Delay(kFlashDelay, &ticks);
  311.     DrawIcon(FALSE);
  312.  
  313.     /*
  314.      * Do the command
  315.      */
  316.     itsSupervisor->DoCommand(GetClickCmd());
  317. }
  318.  
  319.  
  320. /*******************************************************************************\
  321. * DoClick                                                                        *
  322. *    Respond to a click. The wantsClicks instance variable must be                *
  323. *    TRUE for this method ever to be called.                                        *
  324. *                                                                                *
  325. \*******************************************************************************/
  326. void CIconBuddy::DoClick(Point hitPt, short modifierKeys, long when)
  327. {
  328.     Rect    iconRect;
  329.  
  330.     if (!IsActive())
  331.         return;
  332.     
  333.     GetIconRect(&iconRect);
  334.     if (PtInIconID(hitPt, &iconRect, align, iconID)) {
  335.         if (Track())
  336.             itsSupervisor->DoCommand(GetClickCmd());
  337.     }
  338. }
  339.  
  340.  
  341. /*******************************************************************************\
  342. * Track                                                                            *
  343. *    Tracks the mouse, returns TRUE if the mouse was in the pane when released.    *
  344. *                                                                                *
  345. \*******************************************************************************/
  346. Boolean CIconBuddy::Track(void)
  347. {
  348.     Boolean    inBtn = TRUE;
  349.     Point    where;
  350.     Rect    iconRect;
  351.         
  352.     DrawIcon(TRUE);
  353.     GetIconRect(&iconRect);
  354.     
  355.     while (StillDown()) {
  356.         GetMouse(&where);
  357.         if (PtInIconID(where, &iconRect, align, iconID)) {
  358.             if (!inBtn) DrawIcon(TRUE);
  359.             inBtn = TRUE;
  360.         }
  361.         else {
  362.             if (inBtn) DrawIcon(FALSE);
  363.             inBtn = FALSE;
  364.         }
  365.     }
  366.  
  367.     if (inBtn)
  368.         DrawIcon(FALSE);
  369.  
  370.     return inBtn;
  371. }
  372.